#-*-coding:utf-8-*-
import sys
import os

from PyQt5.QtCore import *
from PyQt5.uic import loadUi
from graphics import *
from dialogs import *
from trackbar import *
import cv2
import numpy as np
from matplotlib import pyplot as plt



#example类主要实现主功能页面
class example (QMainWindow):
    def __init__(self):
        super(example,self).__init__()
        loadUi('untitled.ui',self)
        self.imgs = []
        self.canny.clicked.connect(self.canny_def)
        self.IMREAD_COLOR.clicked.connect(self.show_img)
        self.blur.clicked.connect(self.blur_def)
        self.boxfiler.clicked.connect(self.boxfiler_def)
        self.Gaussian.clicked.connect(self.Gaussian_def)
        self.median.clicked.connect(self.median_def)
        self.THRESH_BINARY.clicked.connect(self.binary_def)
        self.THRESH_BINARY_INV.clicked.connect(self.binary_inv_def)
        self.THERSH_TRUNC.clicked.connect(self.trunc_def)
        self.THRESH_TOZERO.clicked.connect(self.tozero_def)
        self.THRESH_TOZERO_INV.clicked.connect(self.tozero_inv_def)
        self.IMREAD_GRAYSCALE.clicked.connect(self.IMREAD_GRAYSCALE_def)
        self.MORPH_OPEN.clicked.connect(self.MORPH_OPEN_def)
        self.MORPH_CLOSE.clicked.connect(self.MORPH_CLOSE_def)
        self.MORPH_GRADIENT.clicked.connect(self.GRADIENT_def)
        self.MORPH_TOPHAT.clicked.connect(self.TOPHAT_def)
        self.MORPH_BLACKHAT.clicked.connect(self.BLACKHAT_def)
        self.get_rgb.clicked.connect(self.get_rgb_def)

        # 当左键单击表格的行时，激活click事件
        self.table.itemClicked.connect(self.click)
        self.laplacian.clicked.connect(self.laplacian_def)
        self.robert.clicked.connect(self.robert_def)
        self.prewitt.clicked.connect(self.prewitt_def)
        self.sobel.clicked.connect(self.sobel_def)
        self.scharr.clicked.connect(self.scharr_def)
        self.log.clicked.connect(self.log_def)
        self.circle.clicked.connect(self.circle_def)
        self.line.clicked.connect(self.line_def)
        self.save_img.clicked.connect(self.save_img_def)
        self.insert_img.clicked.connect(self.insert_img_def)

    #插入图片
    def insert_img_def(self):
        # 选择需要处理的图片
        filename, filetype = QFileDialog.getOpenFileName(self, "选择图片", "/", "Excel files(*.png *.jpg)")
        if filename == '':
            pass

        else:
            #插入图片，并传入self.imgs里，激活其他功能
            self.img = cv2.imread(filename)
            self.imgs.append(self.img)

            # 把图片赋予给self.img_gray，以便把图片转为灰度图
            self.img_gray = self.img.copy()
            show_graphics(self, self.img)

    #保存图片
    def save_img_def(self):

        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:
            # 首先选择需要保存的图片
            select_row=self.table.selectedItems()
            if select_row:

                # 获取选中行的行号
                row = self.table.row(select_row[0])
                img_save = self.imgs[row + 1]

                #保存的路径
                filename, filetype = QFileDialog.getSaveFileName(self, "保存图片", "/", "Excel files(*.png *.jpg)")
                if filename == '':
                    pass

                else:

                    # 保存图片
                    cv2.imwrite(filename, img_save)
            else:
                show_mes('请选择需要保存的图片！')




    #数遍单击命令行，显示图片
    def click(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:
            item=self.table.selectedItems()

            # 获取选中行的行号
            row=self.table.row(item[0])
            img=self.imgs[row+1]
            show_graphics(self,img )

    #显示彩色图片
    def show_img(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:
            self.img_gray = cv2.cvtColor(self.img, cv2.IMREAD_GRAYSCALE)

            # 将处理后的图片添加到imgs里，以便调用
            self.imgs.append(self.img_gray)
            show_graphics(self, self.img_gray)
            row = self.table.rowCount()
            self.table.insertRow(row)

            # 将要输入的内容传入item里
            item = QTableWidgetItem("color image")

            # row为第几行，0为第几列，item为输入的内容
            self.table.setItem(row, 0, item)

    #把图片转为灰度图
    def IMREAD_GRAYSCALE_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:
            self.img_gray = self.img
            self.img_gray = cv2.cvtColor(self.img_gray, cv2.COLOR_BGR2GRAY)
            self.imgs.append(self.img_gray)
            show_graphics(self, self.img_gray)
            row = self.table.rowCount()
            self.table.insertRow(row)
            item = QTableWidgetItem("gray image")
            self.table.setItem(row, 0, item)

    #获取图片的RGB值
    def get_rgb_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:
            img = cv2.cvtColor(self.imgs[-1], cv2.COLOR_BGR2RGB)
            plt.subplot(111),plt.imshow(img),plt.title('Get RGB')
            plt.xticks([]),plt.yticks([])
            plt.show()


    #blur算子
    def blur_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            # 获取参数，没参数则跳过
            data = blur_param(self.img_gray, 20)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "Blur ksize:" + str(data[0])
                item = QTableWidgetItem(comments)
                self.table.setItem(row, 0, item)

    #boxfiler算子
    def boxfiler_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:
            # 获取参数，没参数则跳过
            data = boxfiler_param(self.img_gray, 20)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "Boxfiler ksize:" + str(data[0])
                item = QTableWidgetItem(comments)
                self.table.setItem(row, 0, item)


    #高斯滤波算子
    def Gaussian_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            # 获取参数，没参数则跳过
            data = Gaussian_param( self.img_gray,20)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "Gaussian ksize:" + str(data[0])

                # 将要输入的内容传入item里，显示在主界面的表格里
                item = QTableWidgetItem(comments)

                # row为第几行，0为第几列，item为输入的内容
                self.table.setItem(row, 0, item)


    # 中值滤波算子
    def median_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            # 获取参数，没参数则跳过
            data = median_param( self.img_gray, 20)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "Median ksize:" + str(data[0])
                item = QTableWidgetItem(comments)
                self.table.setItem(row, 0, item)

    # 二进制阀值化
    def binary_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data = binary_param( self.img_gray, 255)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "THRESH_BINARY thresh:" +str(data[0])
                items = QTableWidgetItem(comments)  # 将要输入的内容传入item里
                self.table.setItem(row, 0, items)  # row为第几行，0为第几列，item为输入的内容

    # 反二进制阀值化
    def binary_inv_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data = binary_inv_param( self.img_gray, 255)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "THRESH_BINARY_INV thresh:" +str(data[0])
                items = QTableWidgetItem(comments)  # 将要输入的内容传入item里
                self.table.setItem(row, 0, items)  # row为第几行，0为第几列，item为输入的内容


    # 截断阀值化
    def trunc_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data = trunc_param( self.img_gray, 255)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "THRESH_TRUNC thresh:" + str(data[0])
                items = QTableWidgetItem(comments)  # 将要输入的内容传入item里
                self.table.setItem(row, 0, items)  # row为第几行，0为第几列，item为输入的内容

    #反阀值化为0
    def tozero_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data = tozero_param( self.img_gray, 255)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "THRESH_TOZERO thresh:" + str(data[0])
                items = QTableWidgetItem(comments)  # 将要输入的内容传入item里
                self.table.setItem(row, 0, items)  # row为第几行，0为第几列，item为输入的内容

    # 阀值化为0
    def tozero_inv_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data = tozero_inv_param( self.img_gray, 255)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "THRESH_TOZERO_INV thresh:" + str(data[0])
                items = QTableWidgetItem(comments)  # 将要输入的内容传入item里
                self.table.setItem(row, 0, items)  # row为第几行，0为第几列，item为输入的内容


    #开运算
    def MORPH_OPEN_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data = MORPH_OPEN_param( self.img_gray, 20)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "MORPH_OPEN ksize:" + str(data[0])
                item = QTableWidgetItem(comments)  # 将要输入的内容传入item里
                self.table.setItem(row, 0, item)  # row为第几行，0为第几列，item为输入的内容

    # 闭运算
    def MORPH_CLOSE_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data = MORPH_CLOSE_param( self.img_gray, 20)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "MORPH_CLOSE ksize:" + str(data[0])
                item = QTableWidgetItem(comments)  # 将要输入的内容传入item里
                self.table.setItem(row, 0, item)  # row为第几行，0为第几列，item为输入的内容

    # 梯度运算
    def GRADIENT_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data = MORPH_CLOSE_param( self.img_gray, 20)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "MORPH_GRADIENT ksize:" + str(data[0])
                item = QTableWidgetItem(comments)  # 将要输入的内容传入item里
                self.table.setItem(row, 0, item)  # row为第几行，0为第几列，item为输入的内容

    # 顶帽运算
    def TOPHAT_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data = TOPHAT_param( self.img_gray, 20)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "MORPH_TOPHAT ksize:" + str(data[0])
                item = QTableWidgetItem(comments)  # 将要输入的内容传入item里
                self.table.setItem(row, 0, item)  # row为第几行，0为第几列，item为输入的内容

    # 黑帽运算
    def BLACKHAT_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data = BLACKHAT_param( self.img_gray, 20)
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "MORPH_BLACKHAT ksize:" + str(data[0])
                item = QTableWidgetItem(comments)  # 将要输入的内容传入item里
                self.table.setItem(row, 0, item)  # row为第几行，0为第几列，item为输入的内容

    #canny边缘检测算子
    def canny_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data=canny_params(self.img_gray)#获取参数，没参数则跳过
            if data==None:
                pass
            else:
                self.img_gray =data[2]
                self.imgs.append(self.img_gray)
                show_graphics(self,self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments="Canny threshold1:"+str(data[0])+"，threshold2:"+str(data[1])
                item=QTableWidgetItem(comments)#将要输入的内容传入item里
                self.table.setItem(row,0,item)#row为第几行，0为第几列，item为输入的内容




 #laplacian边缘检测算子
    def laplacian_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data = Laplacian_param(self.img_gray,15)  # 获取参数，没参数则跳过
            if data == None:
                pass
            else:
                self.img_gray = data[1]
                self.imgs.append(self.img_gray)
                show_graphics(self, self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments = "Laplacian ksize:" + str(data[0])
                item = QTableWidgetItem(comments)  # 将要输入的内容传入item里
                self.table.setItem(row, 0, item)  # row为第几行，0为第几列，item为输入的内容

    # robert边缘检测算子
    def robert_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            # Roberts算子
            kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
            kernely = np.array([[0, -1], [1, 0]], dtype=int)
            x = cv2.filter2D(self.img_gray, cv2.CV_16S, kernelx)
            y = cv2.filter2D(self.img_gray, cv2.CV_16S, kernely)
            # 转uint8
            absX = cv2.convertScaleAbs(x)
            absY = cv2.convertScaleAbs(y)
            self.img_gray = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
            self.imgs.append(self.img_gray)
            show_graphics(self, self.img_gray)
            row = self.table.rowCount()
            self.table.insertRow(row)
            comments = "robert"
            item = QTableWidgetItem(comments)  # 将要输入的内容传入item里
            self.table.setItem(row, 0, item)  # row为第几行，0为第几列，item为输入的内容

    # prewitt边缘检测算子
    def prewitt_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            # prewitt算子
            kernelx = np.array([[1,1, 1], [0, 0,0],[-1, -1,-1]], dtype=int)
            kernely = np.array([[-1,0, 1], [-1, 0,1],[-1, 0,1]], dtype=int)
            x = cv2.filter2D(self.img_gray, cv2.CV_16S, kernelx)
            y = cv2.filter2D(self.img_gray, cv2.CV_16S, kernely)
            # 转uint8
            absX = cv2.convertScaleAbs(x)
            absY = cv2.convertScaleAbs(y)
            self.img_gray = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
            self.imgs.append(self.img_gray)
            show_graphics(self, self.img_gray)
            row = self.table.rowCount()
            self.table.insertRow(row)
            comments = "prewitt"
            item = QTableWidgetItem(comments)  # 将要输入的内容传入item里
            self.table.setItem(row, 0, item)  # row为第几行，0为第几列，item为输入的内容

    # sobel边缘检测算子
    def sobel_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            # sobel算子,分别求下x，y的一阶导
            x = cv2.Sobel(self.img_gray, cv2.CV_16S, 1,0)
            y = cv2.Sobel(self.img_gray, cv2.CV_16S, 0,1)

            # 转uint8
            absX = cv2.convertScaleAbs(x)
            absY = cv2.convertScaleAbs(y)
            self.img_gray = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
            self.imgs.append(self.img_gray)
            show_graphics(self, self.img_gray)
            row = self.table.rowCount()
            self.table.insertRow(row)
            comments = "sobel"
            item = QTableWidgetItem(comments)  # 将要输入的内容传入item里
            self.table.setItem(row, 0, item)  # row为第几行，0为第几列，item为输入的内容

    # scharr边缘检测算子
    def scharr_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            # scharr算子,分别求下x，y的一阶导
            x = cv2.Scharr(self.img_gray, cv2.CV_32F, 1, 0)
            y = cv2.Scharr(self.img_gray, cv2.CV_32F, 0, 1)

            # 转uint8
            absX = cv2.convertScaleAbs(x)
            absY = cv2.convertScaleAbs(y)
            self.img_gray = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
            self.imgs.append(self.img_gray)
            show_graphics(self, self.img_gray)
            row = self.table.rowCount()
            self.table.insertRow(row)
            comments = "scharr"
            item = QTableWidgetItem(comments)  # 将要输入的内容传入item里
        self.table.setItem(row, 0, item)  # row为第几行，0为第几列，item为输入的内容

    #log_边缘检测算子
    def log_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data=log_params(self.img_gray)#获取参数，没参数则跳过
            if data==None:
                pass
            else:
                self.img_gray =data[2]
                self.imgs.append(self.img_gray)
                show_graphics(self,self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments="log gauss:"+str(data[0])+"，lapla:"+str(data[1])
                item=QTableWidgetItem(comments)#将要输入的内容传入item里
                self.table.setItem(row,0,item)#row为第几行，0为第几列，item为输入的内容

    #circle边缘检测算子
    def circle_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data=circle_params(self.img_gray,self.img)#获取参数，没参数则跳过
            if data==None:
                pass
            else:
                self.img_gray =data[0]
                self.imgs.append(self.img_gray)
                show_graphics(self,self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments="circle minDist:"+str(data[1])+"，param1:"+str(data[2])+"，param2:"+str(data[3])+"，minRadius:"+str(data[4])+"，maxRadius:"+str(data[5])
                item=QTableWidgetItem(comments)#将要输入的内容传入item里
                self.table.setItem(row,0,item)#row为第几行，0为第几列，item为输入的内容

    #line边缘检测算子
    def line_def(self):
        #如果self.imgs为空，则未插入图片，一切功能不能使用
        if self.imgs==[]:
            show_mes('请插入图片！')
        else:

            data=line_params(self.img_gray,self.img)#获取参数，没参数则跳过
            if data==None:
                pass
            else:
                self.img_gray =data[0]
                self.imgs.append(self.img_gray)
                show_graphics(self,self.img_gray)
                row = self.table.rowCount()
                self.table.insertRow(row)
                comments="threshold:"+str(data[1])+"，minlinelength:"+str(data[2])+"，maxlinegap:"+str(data[3])
                item=QTableWidgetItem(comments)#将要输入的内容传入item里
                self.table.setItem(row,0,item)#row为第几行，0为第几列，item为输入的内容


if __name__=='__main__':
    app=QApplication(sys.argv)
    ex = example()
    ex.showMaximized()
    ex.show()
    sys.exit(app.exec())

